<?php
/**
 * 轻舟CMS(QZLOG)
 *
 * 一款基于PHP+MYSQL的开源内容管理系统，模板标签简单、可扩展性强，利于二次开发，轻松建站的首选利器。
 *
 * @package     QZLOG
 * @license     http://www.qzlog.com/license
 * @link        http://www.qzlog.com
 * @mail        info@shyohan.com
 * @since       Version 3.0
 * @copyright   Copyright (c) 2015 - 2017 上海优翰信息科技有限公司. All rights reserved.
 */

defined('IN_QZLOG') OR exit('QZLOG:No direct script access allowed!');

/**
 * 自定义函数
 * @author LINK <link@shyohan.com>
 */

/**
 * 框架内部默认ajax返回
 * @param string $info 提示信息
 * @param string $alert 父层弹框信息
 * @param bool $close 是否关闭当前层
 * @param string $redirect 是否重定向
 * @param string $url 重定向地址
 * @param string $data 附加数据
 * @param string $status y|n 状态，y成功，n失败
 */
function qz_ajax_return($info = '操作成功', $alert = '', $close = false, $redirect = '', $url = '', $data = '', $status = "y")
{
    if (1 == $redirect) $redirect = 'current';
    if (2 == $redirect) $redirect = 'parent';
    $ret = array(
        'status' => $status,
        'info' => $info,
        'alert' => $alert,
        'close' => $close,
        'redirect' => $redirect,
        'url' => $url,
        'data' => $data
    );

    exit(json_encode($ret));
}

function qz_ajax_return_error($info = '', $alert = '', $close = false, $redirect = '', $url = '', $data = '', $status = "n")
{
    qz_ajax_return($info, $alert, $close, $redirect, $url, $data, $status);
}

/**
 * 节点遍历
 * @param $list
 * @param string $pk
 * @param string $pid
 * @param string $child
 * @param int $root
 * @return array
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
    // 创建Tree
    $tree = array();
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] =& $list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] =& $list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent =& $refer[$parentId];
                    $parent[$child][] =& $list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 统一密码加密方式，如需变动直接修改此处
 * @param $password
 * @return string
 */
function password_hash_my($password)
{
    return hash("md5", $password);
}

/**
 * 生成随机字符串
 * @param string $prefix
 * @return string
 */
function get_random($prefix = '')
{
    return base_convert(time() * 1000, 10, 36) . "_" . base_convert(microtime(), 10, 36) . uniqid();
}

/**
 * 创建面包屑导航
 */
function make_bread($flour)
{
    $bread = array();
    foreach ($flour as $name => $link) {
        if (empty($link)) {
            $bread[] = "<span class=\"c-gray en\">$name</span>";
        } else {
            $bread[] = "<span class=\"c-gray en\"><a href=\"$link\" target=\"_self\">$name</a></span>";
        }
    }
    return implode('<span class="c-gray en">&gt;</span>', $bread);
}

/**
 * 创建随机密码
 * @param int $length
 * @return string
 */
function generate_password($length = 8)
{
    // 密码字符集，可任意添加你需要的字符
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|';

    $password = '';
    for ($i = 0; $i < $length; $i++) {
        // 这里提供两种字符获取方式
        // 第一种是使用 substr 截取$chars中的任意一位字符；
        // 第二种是取字符数组 $chars 的任意元素
        // $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        $password .= $chars[mt_rand(0, strlen($chars) - 1)];
    }

    return $password;
}

/**
 * 检测用户是否登录
 * @return integer 0-未登录，大于0-当前登录用户ID
 */
function is_login()
{
    $user = session('user');
    if (empty($user)) {
        return 0;
    } else {
        return $_SESSION['user']['id'];
    }
}

/**
 * 检测当前用户是否为管理员
 * @return boolean true-管理员，false-非管理员
 */
function is_administrator($uid)
{
    $sUid = implode(',', C('USER_ADMINISTRATOR'));
    if (strstr($sUid, $uid)) {
        return $uid;
    }
    return 0;
}

// 不区分大小写的in_array实现
function in_array_case($value, $array)
{
    return in_array(strtolower($value), array_map('strtolower', $array));
}

/**
 * php5.1 实现json_decode方法
 * @param $json
 * @return mixed
 */
function __json_decode($json)
{
    $comment = false;
    $out = '$x=';
    $x ='';
    for ($i=0; $i<strlen($json); $i++)
    {
        if (!$comment)
        {
            if (($json[$i] == '{') || ($json[$i] == '[')) $out .= ' array(';
            else if (($json[$i] == '}') || ($json[$i] == ']')) $out .= ')';
            else if ($json[$i] == ':') $out .= '=>';
            else $out .= $json[$i];
        }
        else $out .= $json[$i];

        if ($json[$i] == '"' && $json[($i-1)]!="\\") $comment = !$comment;
    }

    eval($out . ';');
    return $x;
}

/**
 * php5.1 实现json_encode方法
 * @param $data
 * @return string
 */
function __json_encode($data)
{
    if (is_array($data) || is_object($data)) {
        $islist = is_array($data) && (empty($data) || array_keys($data) === range(0, count($data) - 1));

        if ($islist) {
            $json = '[' . implode(',', array_map('__json_encode', $data)) . ']';
        } else {
            $items = Array();
            foreach ($data as $key => $value) {
                $items[] = __json_encode("$key") . ':' . __json_encode($value);
            }
            $json = '{' . implode(',', $items) . '}';
        }
    } elseif (is_string($data)) {
        # Escape non-printable or Non-ASCII characters.
        # I also put the \\ character first, as suggested in comments on the 'addclashes' page.
        $string = '"' . addcslashes($data, "\\\"\n\r\t/" . chr(8) . chr(12)) . '"';
        $json = '';
        $len = strlen($string);
        # Convert UTF-8 to Hexadecimal Codepoints.
        for ($i = 0; $i < $len; $i++) {

            $char = $string[$i];
            $c1 = ord($char);

            # Single byte;
            if ($c1 < 128) {
                $json .= ($c1 > 31) ? $char : sprintf("\\u%04x", $c1);
                continue;
            }

            # Double byte
            $c2 = ord($string[++$i]);
            if (($c1 & 32) === 0) {
                $json .= sprintf("\\u%04x", ($c1 - 192) * 64 + $c2 - 128);
                continue;
            }

            # Triple
            $c3 = ord($string[++$i]);
            if (($c1 & 16) === 0) {
                $json .= sprintf("\\u%04x", (($c1 - 224) << 12) + (($c2 - 128) << 6) + ($c3 - 128));
                continue;
            }

            # Quadruple
            $c4 = ord($string[++$i]);
            if (($c1 & 8) === 0) {
                $u = (($c1 & 15) << 2) + (($c2 >> 4) & 3) - 1;

                $w1 = (54 << 10) + ($u << 6) + (($c2 & 15) << 2) + (($c3 >> 4) & 3);
                $w2 = (55 << 10) + (($c3 & 15) << 6) + ($c4 - 128);
                $json .= sprintf("\\u%04x\\u%04x", $w1, $w2);
            }
        }
    } else {
        # int, floats, bools, null
        $json = strtolower(var_export($data, true));
    }
    return $json;
}

/**
 * 将全角字符转为半角字符 如】转为]
 * @param type $str
 * @return type
 */
function toSemiangle($str)
{
    $arr = array('０' => '0', '１' => '1', '２' => '2', '３' => '3', '４' => '4',
        '５' => '5', '６' => '6', '７' => '7', '８' => '8', '９' => '9',
        'Ａ' => 'A', 'Ｂ' => 'B', 'Ｃ' => 'C', 'Ｄ' => 'D', 'Ｅ' => 'E',
        'Ｆ' => 'F', 'Ｇ' => 'G', 'Ｈ' => 'H', 'Ｉ' => 'I', 'Ｊ' => 'J',
        'Ｋ' => 'K', 'Ｌ' => 'L', 'Ｍ' => 'M', 'Ｎ' => 'N', 'Ｏ' => 'O',
        'Ｐ' => 'P', 'Ｑ' => 'Q', 'Ｒ' => 'R', 'Ｓ' => 'S', 'Ｔ' => 'T',
        'Ｕ' => 'U', 'Ｖ' => 'V', 'Ｗ' => 'W', 'Ｘ' => 'X', 'Ｙ' => 'Y',
        'Ｚ' => 'Z', 'ａ' => 'a', 'ｂ' => 'b', 'ｃ' => 'c', 'ｄ' => 'd',
        'ｅ' => 'e', 'ｆ' => 'f', 'ｇ' => 'g', 'ｈ' => 'h', 'ｉ' => 'i',
        'ｊ' => 'j', 'ｋ' => 'k', 'ｌ' => 'l', 'ｍ' => 'm', 'ｎ' => 'n',
        'ｏ' => 'o', 'ｐ' => 'p', 'ｑ' => 'q', 'ｒ' => 'r', 'ｓ' => 's',
        'ｔ' => 't', 'ｕ' => 'u', 'ｖ' => 'v', 'ｗ' => 'w', 'ｘ' => 'x',
        'ｙ' => 'y', 'ｚ' => 'z',
        '（' => '(', '）' => ')', '〔' => '[', '〕' => ']', '【' => '[',
        '】' => ']', '〖' => '[', '〗' => ']', '“' => '[', '”' => ']',
        '‘' => '[', '’' => ']', '｛' => '{', '｝' => '}', '《' => '<',
        '》' => '>',
        '％' => '%', '＋' => '+', '—' => '-', '－' => '-', '～' => '-',
        '：' => ':', '。' => '.', '、' => ',', '，' => ',', '、' => '.',
        '；' => ';', '？' => '?', '！' => '!', '…' => '-', '‖' => '|',
        '”' => '"', '’' => '`', '‘' => '`', '｜' => '|', '〃' => '"',
        '　' => ' ');

    return strtr($str, $arr);
}

// 分析枚举类型字段值 格式 a:名称1,b:名称2
// 暂时和 parse_config_attr功能相同
// 但请不要互相使用，后期会调整
function parse_field_attr($string) {
    if(0 === strpos($string,':')){
        // 采用函数定义
        return   eval(substr($string,1).';');
    }
    $array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
    if(strpos($string,':')){
        $value  =   array();
        foreach ($array as $val) {
            list($k, $v) = explode(':', $val);
            $value[$k]   = $v;
        }
    }else{
        $value  =   $array;
    }
    return $value;
}

// 获取属性类型信息
function get_attribute_type($type=''){
    static $_type = array(
        'num'       =>  array('数字','int(10) UNSIGNED NOT NULL'),
        'string'    =>  array('字符串','varchar(255) NOT NULL'),
        'textarea'  =>  array('文本框','text NOT NULL'),
        'datetime'  =>  array('时间','int(10) NOT NULL'),
        'bool'      =>  array('布尔','tinyint(2) NOT NULL'),
        'select'    =>  array('枚举','char(50) NOT NULL'),
        'radio'		=>	array('单选','char(10) NOT NULL'),
        'checkbox'	=>	array('多选','varchar(100) NOT NULL'),
        'editor'    =>  array('编辑器','text NOT NULL'),
        'picture'   =>  array('上传图片','int(10) UNSIGNED NOT NULL'),
        'file'    	=>  array('上传附件','int(10) UNSIGNED NOT NULL'),
    );
    return $type?$_type[$type][0]:$_type;
}